package main

import (
	"fmt"
	"math/rand"
	"time"
	"strings"
)

const delay int = 1000
const gridX int = 10
const gridY int = 10
	
var grid [gridY][gridX]byte

var length byte = 4
var dir byte = 0

var nextHeadX int = 0
var nextHeadY int = 0
var food bool = false
var nextFood bool = false
var dead bool = false

func main() {
	
	for x :=0;x<gridX;x++{
		for y :=0;y<gridX;y++{
			grid[y][x]=0
		}
	}
	
	random := rand.New(rand.NewSource(324))
	random.Seed(432534)
	 randX := random.Intn(gridX)
	for randX >= gridX||randX<0 {
		randX = random.Intn(gridX)
	}
	randY := random.Intn(gridY)
	for randY >= gridY||randY<0 {
		randY = random.Intn(gridY)
	}
//	randY:=5
//	randX:=5
	grid[randY][randX] = 1
	if(randY+1)>gridY-1{
		grid[randY-gridY+1][randX] = 2
	}else{
		grid[randY+1][randX] = 2
	}
	if(randY+2)>gridY-1{
		grid[randY-gridY+2][randX] = 3
	}else{
		grid[randY+2][randX] = 3
	}
	if(randY+3)>gridY-1{
		grid[randY-gridY+3][randX] = 4
	}else{
		grid[randY+3][randX] = 4
	}
	randX = random.Intn(gridX)
	for randX >= gridX||randX<0 {
		randX = random.Intn(gridX)
	}
	randY = random.Intn(gridY)
	for randY >= gridY||randX<0 {
		randY = random.Intn(gridY)
	}
//	randX = 5
//	randY= 0
	grid[randY][randX] = 255

	for i:=0; i<15&&!dead;i++{
		loop()
		draw()
		time.Sleep(1000 * time.Millisecond)
	}
}

func loop(){
	findNextHead()
	if !dead {
		tailX,tailY,tail:=getTile(length)
		if tail {
			setPos(0,tailY,tailX)
		}else{
			tailX,tailY,_=getTile(length+100)
			setPos(length+1,tailY,tailX)
			length++
		}	
		for i := length-1; i>0; i-- {
			tileX, tileY, exists := getTile(i)
			if exists{
			setPos(i+1,tileY,tileX)
			}
		}
		if food {
			foodX, foodY,_ :=getTile(2)
			grid[foodY][foodX]=101
			food=false
		}
		for i := length+100; i>100; i-- {
		tileX, tileY,exists := getTile(i)
			if exists{
				setPos(i+1,tileY,tileX)
			}
		}
		setPos(1,nextHeadY,nextHeadX)
		food=nextFood
	}
}

func setPos(value byte, y int, x int){
	if y==gridY {
		y=0
	}else if y==255 {
		y=gridY-1
	}
	if x==gridX {
		x=0
	}else if x==255 {
		x=gridX-1
	}
	grid[y][x] = value
}

func getNewDir() byte{
	// TODO add input
	return dir
}

func nextHead(x,y int){
	nextHeadX=x
	nextHeadY=y
	if nextHeadX==-1{
		nextHeadX=gridX-1
	}else if nextHeadX==gridX{
		nextHeadX=0
	}
	if nextHeadY==-1{
		nextHeadY=gridY-1
	}else if nextHeadY==gridY{
		nextHeadY=0
	}
	if grid[nextHeadY][nextHeadX]==255 {
		nextFood=true
	}else if grid[nextHeadY][nextHeadX]!=0 {
		nextFood=false
		dead=true
	}else{
		nextFood=false
	}
}

func findNextHead(){
	headX, headY,_ := getTile(1)
	if getNewDir()==0 {
		if dir != 2 {
			dir = 0
			nextHead(headX,headY-1)
		}else{
			dir = 2
			nextHead(headX,headY+1)
		}
	}else if getNewDir()==1 {
		if dir != 3 {
			dir = 1
			nextHead(headX+1,headY)
		}else{
			dir = 3
			nextHeadX=headX-1
			nextHeadY=headY
			nextHead(headX-1,headY)
		}
		}else if getNewDir()==2 {
		if dir != 0 {
			dir = 2
			nextHead(headX,headY+1)
		}else{
			dir = 0
			nextHead(headX,headY-1)
		}
	}else if getNewDir()==3 {
		if dir != 1 {
			dir = 3
			nextHead(headX-1,headY)
		}else{
			dir = 1
			nextHead(headX+1,headY)
		}
	}
}

func getTile(tile byte) (int,int,bool){
	for y := 0;y<gridY;y++ {
		for x := 0;x<gridX;x++ {
			if grid[y][x] == tile{
				return x,y,true
			}
		}
	}
	return 0,0,false
}

func draw(){
	if !dead{
		var board [gridY+2]string
		row := make([]string,gridX+2)
		for x:=0;x<gridX+2;x++{
			row[x]="-"
		}
		board[0]=strings.Join(row,"")
		board[gridY+1]=strings.Join(row,"")
		for y := 1;y<gridY+1;y++ {
			rows := make([]string,gridX+2)
			for x := 0;x<gridX+2;x++ {
				if x==0||x==gridX+1{
					rows[x]= "|"
				}else if grid[y-1][x-1] == 0{
					rows[x]= " "
				}else if grid[y-1][x-1] == 255{
					rows[x]= "O"
				}else if grid[y-1][x-1] == 1{
					if dir==0{
						rows[x]= "A"
					}else if dir==1{
						rows[x]= ">"
					}else if dir==2{
						rows[x]= "V"
					}else{
						rows[x]= "<"
					}
				}else if grid[y-1][x-1] == 254{ //wall
					rows[x]= "#"
				}else{
					rows[x]= "*"
				}
			}
			board[y]=strings.Join(rows,"")
		}
		
		for i := 0; i<gridY+2; i++ {
			fmt.Println(board[i])
		}
		fmt.Println(" ")
	}else{
		fmt.Println("Game Over")
	}
}